package com.hxzy.framework.xss.filter;

import com.hxzy.framework.xss.config.XssProperties;
import com.hxzy.framework.xss.core.XssCleaner;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author wy
 * @Description  springmvc中实现  servlet中的Filter过滤器方式
 * @Date 2024/1/22 17:39
 * @Version 1.0
 */
public class XssFilter extends OncePerRequestFilter {
    /**
     * 属性
     */
    private final XssProperties properties;
    /**
     * 路径匹配器
     */
    private final PathMatcher pathMatcher;

    private final XssCleaner xssCleaner;

    public XssFilter(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) {
        this.properties = properties;
        this.pathMatcher = pathMatcher;
        this.xssCleaner = xssCleaner;
    }

    /**
     *  filter过滤器代码
     * @param httpServletRequest
     * @param httpServletResponse
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        //制作一个包装类，让Stream流能够被多次读取
        filterChain.doFilter(new XssRequestWrapper(httpServletRequest, xssCleaner), httpServletResponse);
    }

    /**
     * 哪些请求地址不需要做xss过滤的
     * @param request
     * @return
     * @throws ServletException
     */
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        // 如果关闭，则不过滤
        if (!properties.isEnable()) {
            return true;
        }

        // 如果匹配到无需过滤，则不过滤
        String uri = request.getRequestURI();
        return properties.getExcludeUrls().stream().anyMatch(excludeUrl -> pathMatcher.match(excludeUrl, uri));
    }
}
